#include "game.hpp"
#include <utility>
#include <iostream>
#include <GL/glut.h>
extern double gettime_f();
game::game(int w, int h, falling_things* gm):
	m_size(w,h),
	m_mice(0,0),
	m_last_update_time(gettime_f()),
	m_last_motion_time(m_last_update_time),
	m_game_field(gm)
{
}

void game::paint()
{
	//тут можно нарисовать задний фон
	m_game_field->paint();
	//рисуем передний план
	for(auto iter=m_items.begin(); iter!=m_items.end(); ++iter)
		iter->paint();
	m_game_field->post_paint();
}
//обновляем положения объектов
bool game::update_scene()
{
	//узнаем сколько времени прошло с последнего вызова этой функции
	double newtime=gettime_f();
	double dtime=newtime-m_last_update_time;
	if(dtime<0)dtime=0.0;
	m_last_update_time=newtime;
	//для всякой мишуры на заднем плане тоже нужна анимация
	m_game_field->animate(dtime);
	//для всех бублей переместим их
	unsigned int number_of_bubles(0);
	auto iter=m_items.begin();
	while(iter!=m_items.end())
	{
		iter->animate(*m_game_field,dtime);
		//удаляем все бубли которые ушли с экрана
		if(iter->out_of_screen(*m_game_field))
		{
			iter=m_items.erase(iter);
			continue;
		}
		//остальные суммируем
		++number_of_bubles;
		++iter;
	}
	//если бублей на экране слишком мало, добавляем бублей
	unsigned int spawn_limit=m_game_field->max_bubles_to_spawn(dtime);
	unsigned int max_bubs=m_game_field->expected_number_of_bubles();
	while(spawn_limit-- && number_of_bubles<max_bubs)
	{
		m_items.push_front(flying_thing(*m_game_field));
	}
	return true;//will never leave
}
void game::mouse_enter(int x, int y)
{
	m_last_motion_time=gettime_f();
	m_mice=std::make_pair(x,y);
}
void game::mouse_motion(int x, int y)
{
	//узнаем сколько времени прошло с последнего вызова этой функции
	double newtime=gettime_f();
	double dtime=newtime-m_last_motion_time;
	if(dtime<0)dtime=0.0;
	m_last_motion_time=newtime;
	//найдем с какой скоростью двигалась мышка и куда
	float motion_x=x-m_mice.first;
	float motion_y=m_mice.second-y;
	m_mice=std::make_pair(x,y);
	std::cout.flush();
	//уведомим игру у движении мышки
	float fx(x),fy(m_size.second-y);
	m_game_field->mouse_motion(dtime, fx, fy, motion_x, motion_y);
}
void game::mouse_click(int button, bool down, int x, int y)
{
	mouse_motion(x,y);
	if(!down)return;
	//пересчитаем мышекоординаты в gl и каждый предмет на экране спросим, попали ли мы.
	float gl_x_position=x;
	float gl_y_position=m_size.second-y;
	m_game_field->adjust_mouse_click(gl_x_position, gl_y_position);
	for(auto iter=m_items.rend(); iter!=m_items.rbegin(); --iter)
		if(iter->hit_test(*m_game_field, gl_x_position, gl_y_position))break;
}

void game::resize(int w, int h)
{
	//изменяем размеры игровой зоны
	m_game_field->resize(w,h);	
	m_size=std::make_pair(w,h);
}
